package com.example.wlzz.service.serviceImpl;
import com.alibaba.fastjson.JSON;
import com.example.wlzz.constant.RedisConstant;
import com.example.wlzz.dto.CommentDTO;
import com.example.wlzz.dto.SubreviewDTO;
import com.example.wlzz.dto.TaskDTO;
import com.example.wlzz.dto.TaskNoticeDTO;
import com.example.wlzz.entity.UserInfo;
import com.example.wlzz.entity.User_;
import com.example.wlzz.entity.mongoEntity.*;
import com.example.wlzz.enums.Del_flagEnum;
import com.example.wlzz.enums.MessageEnum;
import com.example.wlzz.enums.ResultEnum;
import com.example.wlzz.enums.TaskEnum;
import com.example.wlzz.form.TaskForm;
import com.example.wlzz.repository.UserInfoRepository;
import com.example.wlzz.repository.UserRepository;
import com.example.wlzz.repository.mongoRepository.*;
import com.example.wlzz.service.TaskService;
import com.example.wlzz.service.Websocket;
import com.example.wlzz.utils.KeyUtil;
import com.example.wlzz.utils.ResultVOUtil;
import com.example.wlzz.utils.WebSocketResultVOUtil;
import com.example.wlzz.vo.CommentPageVO;
import com.example.wlzz.vo.PageVO;
import com.example.wlzz.vo.ResultVO;
import com.example.wlzz.vo.TaskVO;
import com.mongodb.client.MongoCollection;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
@Slf4j
@Transactional
public class TaskServiceImpl implements TaskService{
    @Autowired
    private TaskRepository taskRepository;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private UserInfoRepository userInfoRepository;
    @Autowired
    private CommentRepository commentRepository;
    @Autowired
    private SubreviewRepository subreviewRepository;
    @Autowired
    private TaskReceiveRepository taskReceiveRepository;
    @Autowired
    private LoveTaskRepository loveTaskRepository;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private RelatedRepository relatedRepository;
    @Autowired
    private LoveNoticeRepository loveNoticeRepository;
    @Autowired
    private TaskNoticeStatusMsgRepository taskNoticeStatusMsgRepository;
    @Autowired
    private Websocket websocket;
    @Override
    public PageVO findByCategory(String category, Pageable pageable,int userid,String schoolName) {
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(pageable.getPageNumber(),pageable.getPageSize(),sort);
        Page<Task> taskPage = taskRepository.findByCategoryAndDelFlagAndSchool(category,Del_flagEnum.EXIST.getCode(),schoolName,request);
        PageVO pageVO = getPageToTask(taskPage,pageable.getPageNumber(),pageable.getPageSize(),userid);
        return pageVO;
    }
    @Override
    public PageVO findAll(Pageable pageable,int userid,String schoolName) {
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(pageable.getPageNumber(),pageable.getPageSize(),sort);
        Page<Task> taskPage = taskRepository.findByDelFlagAndSchool(Del_flagEnum.EXIST.getCode(),schoolName,request);
        PageVO pageVO = getPageToTask(taskPage,pageable.getPageNumber(),pageable.getPageSize(),userid);
        return pageVO;
    }

    @Override
    public PageVO getSelfTask(Integer userid, int del_flag,int status, Pageable pageable) {
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(pageable.getPageNumber(),pageable.getPageSize(),sort);
        Page<Task> taskPage = taskRepository.findByUseridAndDelFlagAndStatus(userid,del_flag,status,request);
        PageVO pageVO = getPageToTask(taskPage,pageable.getPageNumber(),pageable.getPageSize(),userid);
        return pageVO;
    }
    @Override
    public PageVO getAllSelfTask(Integer userid, int del_flag, Pageable pageable) {
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(pageable.getPageNumber(),pageable.getPageSize(),sort);
        Page<Task> taskPage = taskRepository.findByUseridAndDelFlag(userid,del_flag,request);
        PageVO pageVO = getPageToTask(taskPage,pageable.getPageNumber(),pageable.getPageSize(),userid);
        return pageVO;
    }

    @Override
    public PageVO getReceiveTask(Integer userid,int status,Pageable pageable) {
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(pageable.getPageNumber(),pageable.getPageSize(),sort);
        Page<TaskReceive> taskReceivePage = taskReceiveRepository.findByUseridAndStatus(userid,status,request);
        List<TaskReceive> receiveList = taskReceivePage.getContent();
        List<Task> taskList = new ArrayList<>();
        for (TaskReceive taskReceive : receiveList) {
            Task task = taskRepository.findBy_idAndDelFlag(taskReceive.getTaskId(),Del_flagEnum.EXIST.getCode());
            taskList.add(task);
        }
        PageVO pageVO = taskListToPage(taskList,pageable.getPageNumber(),pageable.getPageSize(),taskReceivePage.getTotalPages(),userid);
        return pageVO;
    }

    @Override
    public PageVO getAllReceiveTask(Integer userid,Pageable pageable) {
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(pageable.getPageNumber(),pageable.getPageSize(),sort);
        Page<TaskReceive> taskReceivePage = taskReceiveRepository.findByUserid(userid,request);
        List<TaskReceive> receiveList = taskReceivePage.getContent();
        List<Task> taskList = new ArrayList<>();
        for (TaskReceive taskReceive : receiveList) {
            Task task = taskRepository.findBy_idAndDelFlag(taskReceive.getTaskId(),Del_flagEnum.EXIST.getCode());
            taskList.add(task);
        }
        PageVO pageVO = taskListToPage(taskList,pageable.getPageNumber(),pageable.getPageSize(),taskReceivePage.getTotalPages(),userid);
        return pageVO;
    }

    @Override
    public CommentPageVO getCommentForTask(String taskId, int del_flag, Pageable pageable) {
        Sort sort = new Sort(Sort.Direction.ASC,"createTime");   //升序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(pageable.getPageNumber(),pageable.getPageSize(),sort);
        Page<Comment> commentPage = commentRepository.findByTaskIdAndDelFlag(taskId,del_flag,request);
        List<CommentDTO> commentDTOList = new ArrayList<>();
        PageRequest subReviewRequest = PageRequest.of(0,5); //分页  //取出前五条
        for (Comment comment : commentPage.getContent()) {
            CommentDTO commentDTO = new CommentDTO();
            BeanUtils.copyProperties(comment,commentDTO);
            Long getTime = comment.getCreateTime().getTime();
            commentDTO.setCreateTime(getTime.toString());
            UserInfo userInfo = userInfoRepository.findByUserId(comment.getUserid());
            commentDTO.setImgUrl(userInfo.getImgUrl());
            commentDTO.setNickName(userInfo.getNickName());
            CommentPageVO subPageVO = getSubreviewForTask(comment.get_id(),comment.getDelFlag(),subReviewRequest);
            commentDTO.setSubreviewDTO(subPageVO.getDataList());
            commentDTO.setSubreviewCount(subPageVO.getCount());
            commentDTOList.add(commentDTO);
        }
        CommentPageVO pageVO = new CommentPageVO();
        pageVO.setTotalPage(commentPage.getTotalPages());
        pageVO.setSize(commentPage.getSize());
        pageVO.setDataList(commentDTOList);
        pageVO.setCurrentPage(pageable.getPageNumber());
        Long count =  commentPage.getTotalElements();
        pageVO.setCount(count.intValue());
        return pageVO;
    }

    @Override
    public CommentPageVO getSubreviewForTask(String commentId, int del_flag, Pageable pageable) {
        Sort sort = new Sort(Sort.Direction.ASC,"createTime");   //升序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(pageable.getPageNumber(),pageable.getPageSize(),sort);
        Page<Subreview> subreviewPage = subreviewRepository.findByCommentIdAndDelFlag(commentId,del_flag,request);
        List<SubreviewDTO> subreviewDTOList = new ArrayList<>();
        for (Subreview subreview : subreviewPage.getContent()) {
            SubreviewDTO subreviewDTO = new SubreviewDTO();
            BeanUtils.copyProperties(subreview,subreviewDTO);
            Long getTime = subreview.getCreateTime().getTime();
            subreviewDTO.setCreateTime(getTime.toString());
            UserInfo userInfo = userInfoRepository.findByUserId(subreview.getUserid());
            subreviewDTO.setNickName(userInfo.getNickName());
            subreviewDTO.setImgUrl(userInfo.getImgUrl());
            subreviewDTOList.add(subreviewDTO);
        }
        CommentPageVO pageVO = new CommentPageVO();
        pageVO.setTotalPage(subreviewPage.getTotalPages());
        pageVO.setSize(subreviewPage.getSize());
        pageVO.setDataList(subreviewDTOList);
        pageVO.setCurrentPage(pageable.getPageNumber());
        Long count = subreviewPage.getTotalElements();
        pageVO.setCount(count.intValue());
        return pageVO;
    }

    @Override
    public ResultVO saveComment(String token,String taskId,String content) {
        Task task  = taskRepository.findBy_idAndDelFlag(taskId,Del_flagEnum.EXIST.getCode());
        if(task==null){
            return ResultVOUtil.error(ResultEnum.TASK_NO_EXIST.getCode(),ResultEnum.TASK_NO_EXIST.getMessage());
        }
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        UserInfo userInfo = userInfoRepository.findByUserId(user.getUserId());
        Comment comment = new Comment();
        comment.set_id(KeyUtil.genUniqueKey());
        comment.setContent(content);
        comment.setCreateTime(new Date());
        comment.setDelFlag(Del_flagEnum.EXIST.getCode());
        comment.setTaskId(taskId);
        comment.setUserid(user.getUserId());
        commentRepository.save(comment);

        CommentDTO commentDTO = new CommentDTO();
        commentDTO.setNickName(userInfo.getNickName());
        commentDTO.setImgUrl(userInfo.getImgUrl());
        Long getTime = comment.getCreateTime().getTime();
        commentDTO.setCreateTime(getTime.toString());
        commentDTO.set_id(comment.get_id());
        commentDTO.setContent(comment.getContent());
        commentDTO.setTaskId(comment.getTaskId());
        commentDTO.setUserid(comment.getUserid());


        if(!userInfo.getUserId().equals(task.getUserid())){   //自己评论就不通知自己了。
            //这里是做通知类的内容。
            List<Related> relatedList = new ArrayList<>();
            Related related = new Related();
            related.setCommentId(comment.get_id());
            related.setComment(content);
            related.setCreateTime(new Date());
            related.setUserid(userInfo.getUserId());
            related.setNickName(userInfo.getNickName());
            related.setImgUrl(userInfo.getImgUrl());
            TaskNoticeDTO taskNoticeDTO = new TaskNoticeDTO();
            BeanUtils.copyProperties(task,taskNoticeDTO);
            related.setTask(taskNoticeDTO);
            related.setToUserid(task.getUserid());
            relatedList.add(related);
            String result = websocket.sendMessage
                    (JSON.toJSONString(WebSocketResultVOUtil.success(relatedList,MessageEnum.COMMENT.getCode())),task.getUserid());
            if(result==null){
                related.setStatus(0);  //默认状态未发出通知
            }else{
                related.setStatus(1);  //证明对方已在线正常发出
            }
            related.setFlag(String.valueOf(MessageEnum.COMMENT.getCode()));
            relatedRepository.save(related);
        }
        return ResultVOUtil.success(commentDTO);
    }

    @Override
    public ResultVO saveSubreview(String token, String commentId, String content) {
        Comment comment = commentRepository.findBy_idAndDelFlag(commentId,Del_flagEnum.EXIST.getCode());
        if(comment==null){
            return ResultVOUtil.error(ResultEnum.COMMENT_NO_EXIST.getCode(),ResultEnum.COMMENT_NO_EXIST.getMessage());
        }
        Task task = taskRepository.findBy_idAndDelFlag(comment.getTaskId(),Del_flagEnum.EXIST.getCode());
        if(task==null){
            return ResultVOUtil.error(ResultEnum.TASK_NO_EXIST.getCode(),ResultEnum.TASK_NO_EXIST.getMessage());
        }
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        UserInfo userInfo = userInfoRepository.findByUserId(user.getUserId());
        Subreview subreview = new Subreview();
        subreview.set_id(KeyUtil.genUniqueKey());
        subreview.setCommentId(commentId);
        subreview.setContent(content);
        subreview.setCreateTime(new Date());
        subreview.setDelFlag(Del_flagEnum.EXIST.getCode());
        subreview.setUserid(user.getUserId());
        subreviewRepository.save(subreview);
        SubreviewDTO subreviewDTO = new SubreviewDTO();
        subreviewDTO.setImgUrl(userInfo.getImgUrl());
        subreviewDTO.setNickName(userInfo.getNickName());
        Long getTime = subreview.getCreateTime().getTime();
        subreviewDTO.setCreateTime(getTime.toString());
        subreviewDTO.set_id(subreview.get_id());
        subreviewDTO.setCommentId(subreview.getCommentId());
        subreviewDTO.setContent(subreview.getContent());
        subreviewDTO.setUserid(subreview.getUserid());

        //这里是做通知类的内容。
        List<Related> relatedList = new ArrayList<>();
        Related related = new Related();
        related.setSubComment(content);
        related.setCommentId(comment.get_id());
        related.setCreateTime(new Date());
        related.setUserid(userInfo.getUserId());
        related.setNickName(userInfo.getNickName());
        related.setImgUrl(userInfo.getImgUrl());
        TaskNoticeDTO taskNoticeDTO = new TaskNoticeDTO();
        BeanUtils.copyProperties(task, taskNoticeDTO);
        related.setTask(taskNoticeDTO);
        if(!task.getUserid().equals(userInfo.getUserId())) {   //是否评论者是通知任务的发起者
            related.setToUserid(task.getUserid());
            relatedList.clear();
            relatedList.add(related);
            String str = JSON.toJSONString(WebSocketResultVOUtil.success(relatedList, MessageEnum.SUBCOMMENT.getCode()));
            String result = websocket.sendMessage(str, task.getUserid());  //通知任务发布者
            if (result == null) {
                related.setStatus(0);  //默认状态未发出通知
            } else {
                related.setStatus(1);  //证明对方已在线正常发出
            }
            related.setFlag(String.valueOf(MessageEnum.SUBCOMMENT.getCode()));
            relatedRepository.save(related);
        }
        if(!userInfo.getUserId().equals(comment.getUserid())){   //是否通知主评论的人
            relatedList.clear();
            related.setToUserid(comment.getUserid());
            relatedList.add(related);
            String str = JSON.toJSONString(WebSocketResultVOUtil.success(relatedList,MessageEnum.SUBCOMMENT.getCode()));
            String result = websocket.sendMessage(str,comment.getUserid());  //通知任务发布者
            if(result==null){
                related.setStatus(0);  //默认状态未发出通知
            }else{
                related.setStatus(1);  //证明对方已在线正常发出
            }
            related.setFlag(String.valueOf(MessageEnum.SUBCOMMENT.getCode()));
            relatedRepository.save(related);
        }
        return ResultVOUtil.success(subreviewDTO);
    }

    @Override
    public ResultVO deleteTask(String taskId, String token) {
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        Task task =  taskRepository.findBy_idAndDelFlag(taskId,Del_flagEnum.EXIST.getCode());
        if(task==null){
            return ResultVOUtil.error(ResultEnum.TASK_NO_EXIST.getCode(),ResultEnum.TASK_NO_EXIST.getMessage());
        }
        if(TaskEnum.NO_ACCEPT.getCode()!=task.getStatus()){
            return ResultVOUtil.error(ResultEnum.TASK_DELETE_STATUS.getCode(),ResultEnum.TASK_DELETE_STATUS.getMessage());
        }
        if(task.getUserid().equals(user.getUserId())){
            task.setDelFlag(Del_flagEnum.DELETE.getCode());
            taskRepository.save(task);
            return ResultVOUtil.success();
        }else{
            log.error("您操作的不是自己的任务");
            return ResultVOUtil.error(ResultEnum.TASK_ILLEGAL.getCode(),ResultEnum.TASK_ILLEGAL.getMessage());
        }
    }

    @Override
    public ResultVO save(TaskForm taskForm, List<String> files, String token) {
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        UserInfo userInfo = userInfoRepository.findByUserId(user.getUserId());
        if(StringUtils.isEmpty(userInfo.getSchoolName())){
            return ResultVOUtil.error(ResultEnum.SCHOOL_NAME_NULL.getCode(),ResultEnum.SCHOOL_NAME_NULL.getMessage());
        }
        Task task = new Task();
        BeanUtils.copyProperties(taskForm,task);
        task.set_id(KeyUtil.genUniqueKey());
        task.setCreateTime(new Date());
        task.setFiles(files);
        task.setSchool(userInfo.getSchoolName());
        task.setUserid(user.getUserId());
        task.setMoney(taskForm.getMoney());
        task.setDelFlag(Del_flagEnum.EXIST.getCode());
        task.setStatus(TaskEnum.NO_ACCEPT.getCode());
        taskRepository.save(task);
        return ResultVOUtil.success();
    }
    @Override
    public ResultVO cancel_love(String token, String taskId) {
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        LoveTask loveTask =  loveTaskRepository.findByTaskIdAndUserid(taskId,user.getUserId());
        if(loveTask==null){
            return ResultVOUtil.error(ResultEnum.LOVE_NO_EXIST.getCode(),ResultEnum.LOVE_NO_EXIST.getMessage());
        }else{
            loveTaskRepository.delete(loveTask);
            return ResultVOUtil.success();
        }
    }


    @Override
    public ResultVO deleteComment(String token, String commentId, int del_flag) {
        Comment comment = commentRepository.findBy_idAndDelFlag(commentId,del_flag);
        if(comment==null){
            return ResultVOUtil.error(ResultEnum.COMMENT_NO_EXIST.getCode(),ResultEnum.COMMENT_NO_EXIST.getMessage());
        }
        if(Del_flagEnum.DELETE.getCode()==comment.getDelFlag()){
            return ResultVOUtil.error(ResultEnum.DELETE_FAIL.getCode(),ResultEnum.DELETE_FAIL.getMessage());
        }
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        if(user.getUserId()==comment.getUserid()){   //本人操作
            comment.setDelFlag(Del_flagEnum.DELETE.getCode());
            commentRepository.save(comment);
            return ResultVOUtil.success();
        }
        Task task =  taskRepository.findBy_idAndDelFlag(comment.getTaskId(),Del_flagEnum.EXIST.getCode());
        if(user.getUserId().equals(task.getUserid())){  //新增任务主人可以删除评论者的评论
            comment.setDelFlag(Del_flagEnum.DELETE.getCode());
            commentRepository.save(comment);
            return ResultVOUtil.success();
        }
        return ResultVOUtil.error(ResultEnum.IIIEGAL_ACTION.getCode(),ResultEnum.IIIEGAL_ACTION.getMessage());
    }

    @Override
    public ResultVO deleteSubreview(String token, String subreviewId, int del_flag) {
        Subreview subreview = subreviewRepository.findBy_idAndDelFlag(subreviewId,del_flag);
        if(subreview==null){
            return ResultVOUtil.error(ResultEnum.COMMENT_NO_EXIST.getCode(),ResultEnum.COMMENT_NO_EXIST.getMessage());
        }
        if(Del_flagEnum.DELETE.getCode()==subreview.getDelFlag()){
            return ResultVOUtil.error(ResultEnum.DELETE_FAIL.getCode(),ResultEnum.DELETE_FAIL.getMessage());
        }
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        if(user.getUserId()==subreview.getUserid()){   //本人操作
            subreview.setDelFlag(Del_flagEnum.DELETE.getCode());
            subreviewRepository.save(subreview);
            return ResultVOUtil.success();
        }
        Comment comment = commentRepository.findBy_idAndDelFlag(subreview.get_id(),Del_flagEnum.EXIST.getCode());
        if(user.getUserId()==comment.getUserid()){   //本人操作
            subreview.setDelFlag(Del_flagEnum.DELETE.getCode());
            subreviewRepository.save(subreview);
            return ResultVOUtil.success();
        }
        Task task =  taskRepository.findBy_idAndDelFlag(comment.getTaskId(),Del_flagEnum.EXIST.getCode());
        if(user.getUserId()==task.getUserid()){   //本人操作
            subreview.setDelFlag(Del_flagEnum.DELETE.getCode());
            subreviewRepository.save(subreview);
            return ResultVOUtil.success();
        }
        return ResultVOUtil.error(ResultEnum.IIIEGAL_ACTION.getCode(),ResultEnum.IIIEGAL_ACTION.getMessage());

    }
    @Override
    public synchronized ResultVO receviceTask(String token, String taskId) {  //接受任务
        Task task = taskRepository.findBy_idAndDelFlag(taskId,Del_flagEnum.EXIST.getCode());
        if(task==null){  //是否为空
            log.error("【接受任务】任务不存在，taskId={}",taskId);
            return ResultVOUtil.error(ResultEnum.TASK_NO_EXIST.getCode(),ResultEnum.TASK_NO_EXIST.getMessage());
        }
        if(TaskEnum.NO_ACCEPT.getCode()!=task.getStatus()){  //任务状态是否正确
            return ResultVOUtil.error(ResultEnum.RECEVICE_ERROR_STATUS.getCode(),ResultEnum.RECEVICE_ERROR_STATUS.getMessage());
        }
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        if(task.getUserid().equals(user.getUserId())){  //判断任务是否是本人。
            return ResultVOUtil.error(ResultEnum.RECEVICE_MYSELF.getCode(),ResultEnum.RECEVICE_MYSELF.getMessage());
        }
        TaskReceive recevies =  taskReceiveRepository.findByTaskIdAndUserid(taskId,user.getUserId());
        if(recevies!=null){   //已经接受过该任务
            return ResultVOUtil.error(ResultEnum.TASK_REPEAT_RECEVICE.getCode(),ResultEnum.TASK_REPEAT_RECEVICE.getMessage());
        }
        //查询该用户接单的时候是否还有其他未完成的任务
        List<TaskReceive> recevies2 = taskReceiveRepository.findByUseridAndStatus(user.getUserId(),TaskEnum.ACCEPT.getCode());
        if(recevies2.size()>=1){
            log.error("当前接受任务超过个数");
            return ResultVOUtil.error(ResultEnum.RECEVICE_MANY.getCode(),ResultEnum.RECEVICE_MANY.getMessage());
        }
        TaskReceive taskReceive = new TaskReceive();
        taskReceive.set_id(KeyUtil.genUniqueKey());
        taskReceive.setCreateTime(new Date());
        taskReceive.setStatus(TaskEnum.ACCEPT.getCode());
        taskReceive.setTaskId(task.get_id());
        taskReceive.setUserid(user.getUserId());
        taskReceiveRepository.save(taskReceive);
        task.setStatus(TaskEnum.ACCEPT.getCode()); //任务状态改变
        taskRepository.save(task);

        UserInfo userInfo = userInfoRepository.findByUserId(user.getUserId());
        taskNoticeStatusMsgUtil(task,userInfo,"您发布的任务已有用户接单");

        return ResultVOUtil.success();
    }

    @Override
    public ResultVO cancel_taskRecvice(String token, String taskId) {
        Task task = taskRepository.findBy_idAndDelFlag(taskId,Del_flagEnum.EXIST.getCode());
        if(task==null){  //是否为空
            log.error("【取消任务】任务不存在,taskId={}",taskId);
            return ResultVOUtil.error(ResultEnum.TASK_NO_EXIST.getCode(),ResultEnum.TASK_NO_EXIST.getMessage());
        }
        if(TaskEnum.ACCEPT.getCode()==task.getStatus()){  //任务状态是否正确
            //去redis查询
            String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
            User_ user = userRepository.findByPhone(phoneToken);
            TaskReceive taskReceive = taskReceiveRepository.findByTaskIdAndUserid(taskId,user.getUserId());
            if(taskReceive==null){
                log.error("【取消任务】接受任务列表内容不存在,taskId={}",taskId);
                return ResultVOUtil.error(ResultEnum.NO_RECEVICE_TASK.getCode(),ResultEnum.NO_RECEVICE_TASK.getMessage());
            }
            if(TaskEnum.ACCEPT.getCode()!=taskReceive.getStatus()){
                log.error("【取消任务】接单状态不正确,taskId={}",taskReceive);
                return ResultVOUtil.error(ResultEnum.RECEVICE_ERROR_STATUS.getCode(),ResultEnum.RECEVICE_ERROR_STATUS.getMessage());
            }
            Date createTime = taskReceive.getCreateTime();  //获取接单任务的时间
            Date nowDate = new Date();  //获取现在的时间
            Long endTime = nowDate.getTime()-createTime.getTime();
            if(endTime.intValue()>1000*60*5){  //超过3分钟
                log.error("【取消任务】超过5分钟期限,taskId={}",taskReceive);
                return ResultVOUtil.error(ResultEnum.TASK_CANCEL_DELAY.getCode(),ResultEnum.TASK_CANCEL_DELAY.getMessage());
            }else{
                task.setStatus(TaskEnum.NO_ACCEPT.getCode());  //修改任务状态
                taskRepository.save(task);
                taskReceive.setStatus(TaskEnum.NO_ACCEPT.getCode());
                taskReceiveRepository.save(taskReceive);

                UserInfo userInfo = userInfoRepository.findByUserId(user.getUserId());
                taskNoticeStatusMsgUtil(task,userInfo,"您发布的任务接单者已取消");
                return ResultVOUtil.success();
            }
        }else{
            log.error("【取消任务】任务状态不正确,taskId={}",taskId);
            return ResultVOUtil.error(ResultEnum.RECEVICE_ERROR_STATUS.getCode(),ResultEnum.RECEVICE_ERROR_STATUS.getMessage());
        }
    }

    @Override
    public ResultVO loveTask(String token, String taskId) {
        Task task = taskRepository.findBy_idAndDelFlag(taskId,Del_flagEnum.EXIST.getCode());
        if(task==null){
            return ResultVOUtil.error(ResultEnum.TASK_NO_EXIST.getCode(),ResultEnum.TASK_NO_EXIST.getMessage());
        }
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        UserInfo userInfo = userInfoRepository.findByUserId(user.getUserId());
        LoveTask mongoLoveTask = loveTaskRepository.findByTaskIdAndUserid(taskId,user.getUserId());
        if(mongoLoveTask!=null){
            return ResultVOUtil.error(ResultEnum.LOVE_TASK_EXIST.getCode(),ResultEnum.LOVE_TASK_EXIST.getMessage());
        }
        LoveTask loveTask = new LoveTask();
        loveTask.setTaskId(taskId);
        loveTask.setUserid(user.getUserId());
        loveTaskRepository.save(loveTask);
        if(!task.getUserid().equals(userInfo.getUserId())){
            //这里是做通知类的内容。
            List<LoveNotice> loveNoticeList = new ArrayList<>();
            LoveNotice loveNotice = new LoveNotice();
            loveNotice.setCreateTime(new Date());
            loveNotice.setUserid(userInfo.getUserId());
            loveNotice.setNickName(userInfo.getNickName());
            loveNotice.setImgUrl(userInfo.getImgUrl());
            TaskNoticeDTO taskNoticeDTO = new TaskNoticeDTO();
            BeanUtils.copyProperties(task,taskNoticeDTO);
            loveNotice.setTask(taskNoticeDTO);
            loveNotice.setToUserid(task.getUserid());
            loveNoticeList.add(loveNotice);
            String result = websocket.sendMessage
                    (JSON.toJSONString(WebSocketResultVOUtil.success(loveNoticeList,MessageEnum.LOVE.getCode())),task.getUserid());
            if(result==null){
                loveNotice.setStatus(0);  //默认状态未发出通知
            }else{
                loveNotice.setStatus(1);  //证明对方已在线正常发出
            }
            loveNotice.setFlag(String.valueOf(MessageEnum.LOVE.getCode()));
            loveNoticeRepository.save(loveNotice);
        }
        return ResultVOUtil.success();
    }

    @Override
    public ResultVO successTask(String token, String taskId) {
        Task task = taskRepository.findBy_idAndDelFlag(taskId,Del_flagEnum.EXIST.getCode());
        if(task==null){
            return ResultVOUtil.error(ResultEnum.TASK_NO_EXIST.getCode(),ResultEnum.TASK_NO_EXIST.getMessage());
        }
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        TaskReceive taskReceive =  taskReceiveRepository.findByTaskIdAndUserid(taskId,user.getUserId());
        if(taskReceive==null){
            log.error("【完成任务】接受任务列表内容不存在,taskId={}",taskId);
            return ResultVOUtil.error(ResultEnum.NO_RECEVICE_TASK.getCode(),ResultEnum.NO_RECEVICE_TASK.getMessage());
        }else{
            if(taskReceive.getStatus()==TaskEnum.ACCEPT.getCode()){
                if(user.getUserId().equals(taskReceive.getUserid())){
                    Date createTime = taskReceive.getCreateTime();  //获取接单任务的时间
                    Date nowDate = new Date();  //获取现在的时间
                    Long endTime = nowDate.getTime()-createTime.getTime();
                    if(endTime.intValue()<1000*60*3){  //超过3分钟
                        log.error("【完成任务】小于3分钟期限,taskId={}",taskReceive);
                        return ResultVOUtil.error(ResultEnum.TASK_SUCCES_TIME.getCode(),ResultEnum.TASK_SUCCES_TIME.getMessage());
                    }
                    task.setStatus(TaskEnum.COMPLETE.getCode());
                    taskReceive.setStatus(TaskEnum.COMPLETE.getCode());
                    taskReceiveRepository.save(taskReceive);
                    taskRepository.save(task);
                    UserInfo userInfo = userInfoRepository.findByUserId(user.getUserId());
                    taskNoticeStatusMsgUtil(task,userInfo,"接单者已完成您发布的任务");
                    return ResultVOUtil.success();
                }else{
                    return ResultVOUtil.error(ResultEnum.SUCCESS_TASK_ERROR.getCode(),ResultEnum.SUCCESS_TASK_ERROR.getMessage());
                }
            }else{
                return ResultVOUtil.error(ResultEnum.RECEVICE_ERROR_STATUS.getCode(),ResultEnum.RECEVICE_ERROR_STATUS.getMessage());
            }
        }
    }


    public PageVO getPageToTask(Page<Task> taskPage, Integer page, Integer size,int userid){   //半个工具类，用来封装数据
        List<Task> taskList = taskPage.getContent();  //得到所有的List
        PageVO pageVO =  taskListToPage(taskList,page,size,taskPage.getTotalPages(),userid);
        return pageVO;
    }
    public PageVO taskListToPage(List<Task> taskList,Integer page, Integer size,Integer totalPages,int userid){
        List<TaskDTO> taskDTOS = new ArrayList<>();
        for (Task task : taskList) {
            TaskDTO taskDTO = new TaskDTO();
            BeanUtils.copyProperties(task,taskDTO);
            Long getTime = task.getCreateTime().getTime();
            taskDTO.setCreateTime(getTime.toString());
            taskDTOS.add(taskDTO);
        }
        List<TaskVO> taskVOList = new ArrayList<>();
        MongoCollection<Document> documentMongoCollection =  mongoTemplate.getCollection("loveTask");
        MongoCollection<Document> commentCollention =  mongoTemplate.getCollection("comment");
        for (TaskDTO taskDTO : taskDTOS) {  //重新封装打包数据
            TaskVO taskVO = new TaskVO();
            UserInfo userInfo = userInfoRepository.findByUserId(taskDTO.getUserid());
            taskVO.setNickName(userInfo.getNickName());
            taskVO.setImgUrl(userInfo.getImgUrl());
            taskVO.setTask(taskDTO);
            Document document1 = new Document();
            document1.put("taskId",taskDTO.get_id());
            Document document2 = new Document();  //comment的条件
            document2.put("taskId",taskDTO.get_id());
            document2.put("delFlag",Del_flagEnum.EXIST.getCode());
            Long count =  documentMongoCollection.count(document1);
            LoveTask mongoLoveTask = loveTaskRepository.findByTaskIdAndUserid(taskDTO.get_id(),userid);
            if(mongoLoveTask!=null){
                taskVO.setLoveFlag(1);
            }else{
                taskVO.setLoveFlag(0);
            }
            taskVO.setLove(count.intValue());
            taskVO.setUserid(taskDTO.getUserid());
            Long commentCount =  commentCollention.count(document2);
            taskVO.setCommentCount(commentCount.intValue());

            //增加接单者
            if(taskDTO.getStatus()!=0){  //表示已被接单
                TaskReceive receive =  taskReceiveRepository.findByTaskIdAndStatus(taskVO.getTask().get_id(),taskDTO.getStatus());
                if(receive!=null){
                    UserInfo re_userInfo = userInfoRepository.findByUserId(receive.getUserid());
                    taskVO.setRe_imgUrl(re_userInfo.getImgUrl());
                    taskVO.setRe_nickName(re_userInfo.getNickName());
                    taskVO.setRe_userid(re_userInfo.getUserId());
                }
            }
            taskVOList.add(taskVO);
        }
        PageVO pageVO = new PageVO();
        pageVO.setCurrentPage(page);
        pageVO.setDataList(taskVOList);  //重新封装数据
        pageVO.setSize(size);
        pageVO.setTotalPage(totalPages);
        return pageVO;
    }

    @Override
    public ResultVO taskIdForTask(String token, String taskId) {
        //去redis查询
        String phoneToken = redisTemplate.opsForValue().get(String.format(RedisConstant.LOGIN_SUCCESS_TOKEN, token));
        User_ user = userRepository.findByPhone(phoneToken);
        UserInfo userInfo = userInfoRepository.findByUserId(user.getUserId());
        TaskVO taskVO = new TaskVO();
        Task task = taskRepository.findBy_idAndDelFlag(taskId,Del_flagEnum.EXIST.getCode());
        if(task==null){
            return ResultVOUtil.error(ResultEnum.TASK_NO_EXIST.getCode(),ResultEnum.TASK_NO_EXIST.getMessage());
        }else{
            UserInfo taskUserInfo  = userInfoRepository.findByUserId(task.getUserid());
            MongoCollection<Document> documentMongoCollection =  mongoTemplate.getCollection("loveTask");
            MongoCollection<Document> commentCollention =  mongoTemplate.getCollection("comment");
            Document document1 = new Document();
            document1.put("taskId",task.get_id());
            Document document2 = new Document();  //comment的条件
            document2.put("taskId",task.get_id());
            document2.put("delFlag",Del_flagEnum.EXIST.getCode());
            Long commentCount =  commentCollention.count(document2);
            Long count =  documentMongoCollection.count(document1);
            LoveTask mongoLoveTask = loveTaskRepository.findByTaskIdAndUserid(task.get_id(),userInfo.getUserId());
            if(mongoLoveTask!=null){
                taskVO.setLoveFlag(1);
            }else{
                taskVO.setLoveFlag(0);
            }
            taskVO.setLove(count.intValue());
            taskVO.setCommentCount(commentCount.intValue());
            taskVO.setUserid(taskUserInfo.getUserId());
            taskVO.setImgUrl(taskUserInfo.getImgUrl());
            taskVO.setNickName(taskUserInfo.getNickName());


            //任务
            TaskDTO taskDTO = new TaskDTO();
            BeanUtils.copyProperties(task,taskDTO);
            Long getTime = task.getCreateTime().getTime();
            taskDTO.setCreateTime(getTime.toString());
            taskVO.setTask(taskDTO);
            //增加接单者
            if(taskDTO.getStatus()!=0){  //表示已被接单
                TaskReceive receive =  taskReceiveRepository.findByTaskIdAndStatus(taskVO.getTask().get_id(),taskDTO.getStatus());
                if(receive!=null){
                    UserInfo re_userInfo = userInfoRepository.findByUserId(receive.getUserid());
                    taskVO.setRe_imgUrl(re_userInfo.getImgUrl());
                    taskVO.setRe_nickName(re_userInfo.getNickName());
                    taskVO.setRe_userid(re_userInfo.getUserId());
                }
            }
            return ResultVOUtil.success(taskVO);
        }
    }

    @Override
    public PageVO getRelated(int userid,Pageable pageable) {
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(pageable.getPageNumber(),pageable.getPageSize(),sort);
        Page<Related> relatedPage = relatedRepository.findByToUserid(userid,request);
        List<Related> relatedList = relatedPage.getContent();
        relatedList.stream().forEach(item ->{
            UserInfo userInfo = userInfoRepository.findByUserId(item.getUserid());
            item.setImgUrl(userInfo.getImgUrl());
            item.setNickName(userInfo.getNickName());
        });
        PageVO pageVO = new PageVO();
        pageVO.setTotalPage(relatedPage.getTotalPages());
        pageVO.setSize(relatedPage.getSize());
        pageVO.setDataList(relatedList);
        pageVO.setCurrentPage(pageable.getPageNumber());
        return pageVO;
    }

    @Override
    public PageVO getLoveNotice(int userid, Pageable pageable) {
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(pageable.getPageNumber(),pageable.getPageSize(),sort);
        Page<LoveNotice> loveNoticePage = loveNoticeRepository.findByToUserid(userid,request);
        List<LoveNotice> loveNoticeList = loveNoticePage.getContent();
        loveNoticeList.stream().forEach(item ->{
            UserInfo userInfo = userInfoRepository.findByUserId(item.getUserid());
            item.setImgUrl(userInfo.getImgUrl());
            item.setNickName(userInfo.getNickName());
        });
        PageVO pageVO = new PageVO();
        pageVO.setTotalPage(loveNoticePage.getTotalPages());
        pageVO.setSize(loveNoticePage.getSize());
        pageVO.setDataList(loveNoticeList);
        pageVO.setCurrentPage(pageable.getPageNumber());
        return pageVO;
    }

    @Override
    public PageVO aboutMeRelated(int userid, Pageable pageable) {
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(pageable.getPageNumber(),pageable.getPageSize(),sort);
        Page<Related> relatedPage = relatedRepository.findByUserid(userid,request);
        List<Related> relatedList = relatedPage.getContent();
        relatedList.stream().forEach(item ->{
            UserInfo userInfo = userInfoRepository.findByUserId(item.getUserid());
            item.setImgUrl(userInfo.getImgUrl());
            item.setNickName(userInfo.getNickName());
        });
        PageVO pageVO = new PageVO();
        pageVO.setTotalPage(relatedPage.getTotalPages());
        pageVO.setSize(relatedPage.getSize());
        pageVO.setDataList(relatedList);
        pageVO.setCurrentPage(pageable.getPageNumber());
        return pageVO;
    }
    @Override
    public PageVO aboutMeLove(int userid, Pageable pageable) {
        Sort sort = new Sort(Sort.Direction.DESC,"createTime");   //降序----根据创建时间来进行降序
        PageRequest request =  PageRequest.of(pageable.getPageNumber(),pageable.getPageSize(),sort);
        Page<LoveNotice> loveNoticePage = loveNoticeRepository.findByUserid(userid,request);
        List<LoveNotice> loveNoticeList = loveNoticePage.getContent();
        loveNoticeList.stream().forEach(item ->{
            UserInfo userInfo = userInfoRepository.findByUserId(item.getUserid());
            item.setImgUrl(userInfo.getImgUrl());
            item.setNickName(userInfo.getNickName());
        });
        PageVO pageVO = new PageVO();
        pageVO.setTotalPage(loveNoticePage.getTotalPages());
        pageVO.setSize(loveNoticePage.getSize());
        pageVO.setDataList(loveNoticeList);
        pageVO.setCurrentPage(pageable.getPageNumber());
        return pageVO;
    }
    //第一个Task是任务，第二个不是任务者的信息，那是成功触发任务事件的用户
    public void taskNoticeStatusMsgUtil(Task task,UserInfo userInfo,String msg){
        try {
            TaskNoticeStatusMsg taskNoticeStatusMsg = new TaskNoticeStatusMsg();
            taskNoticeStatusMsg.setCreateTime(new Date());
            taskNoticeStatusMsg.setFlag(String.valueOf(MessageEnum.TASK_STATUS_MSG.getCode()));
            taskNoticeStatusMsg.setUserid(userInfo.getUserId());  //操作者的用户id
            taskNoticeStatusMsg.setImgUrl(userInfo.getImgUrl());  //操作者的用户头像
            taskNoticeStatusMsg.setMsg(msg);   //提示消息
            taskNoticeStatusMsg.setNickName(userInfo.getNickName());
            TaskNoticeDTO taskNoticeDTO = new TaskNoticeDTO();
            BeanUtils.copyProperties(task, taskNoticeDTO);
            taskNoticeStatusMsg.setTask(taskNoticeDTO);
            taskNoticeStatusMsg.setToUserid(task.getUserid());
            String result = websocket.sendMessage
                    (JSON.toJSONString(WebSocketResultVOUtil.success(taskNoticeStatusMsg, MessageEnum.TASK_STATUS_MSG.getCode())), task.getUserid());
            if ("success".equals(result)) {   //则要保存通知信息。
                taskNoticeStatusMsg.setStatus(1);
            }else{
                taskNoticeStatusMsg.setStatus(0);
            }
            taskNoticeStatusMsgRepository.save(taskNoticeStatusMsg);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

}